// excerpts from http://code.google.com/p/muduo/
//
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.
//
// Author: Shuo Chen (chenshuo at chenshuo dot com)

#pragma once

#include "noncopyable.h"
#include <functional>

namespace learnmuduo
{

class EventLoop;

///
/// A selectable I/O channel.
///
/// This class doesn't own the file descriptor.
/// The file descriptor could be a socket,
/// an eventfd, a timerfd, or a signalfd
class Channel : noncopyable { // I/O 事件封装（Reactor 模式中的“通道”）。; 一个 Channel 对应一个文件描述符，负责记录感兴趣的事件以及实际发生的事件，并在事件就绪时回调用户提供的处理函数。
public:
  typedef std::function<void()> EventCallback;

  Channel(EventLoop *loop, int fd);

  void handleEvent(); // 由 EventLoop 的事件分发阶段调用，根据 revents_ 调用相应回调。
  void setReadCallback(const EventCallback &cb) { readCallback_ = cb; }
  void setWriteCallback(const EventCallback &cb) { writeCallback_ = cb; }
  void setErrorCallback(const EventCallback &cb) { errorCallback_ = cb; }

  int fd() const { return fd_; }
  int events() const { return events_; }
  void set_revents(int revt) { revents_ = revt; }
  bool isNoneEvent() const { return events_ == kNoneEvent; }

  void enableReading() { // 关注可读事件，内部会调用 update() 通知 Poller。
    events_ |= kReadEvent;
    update();
  }

  // for Poller; Poller 相关的辅助接口
  int index() { return index_; }
  void set_index(int idx) { index_ = idx; }

  EventLoop *ownerLoop() { return loop_; }

private:
  void update(); // 通知所属 EventLoop 更新事件关注集合

  static const int kNoneEvent;
  static const int kReadEvent;
  static const int kWriteEvent;

  EventLoop *loop_; // 所属的 EventLoop
  const int fd_; // 被监视的文件描述符
  int events_; // 关心的事件集合
  int revents_; // poll 返回的实际事件
  int index_; // 在 Poller(pollfds_) 中的索引
  EventCallback readCallback_;
  EventCallback writeCallback_;
  EventCallback errorCallback_;
};
} // namespace learnmuduo
